import { createPortal } from 'react-dom';
import { useCallback, useMemo, useState, ReactElement, useRef, MutableRefObject } from 'react';
import { NavBar, ActionSheet, Button, Dialog, Toast } from 'antd-mobile';
import { MoreOutline } from 'antd-mobile-icons';
import { useParams, Outlet } from 'react-router-dom';
import { RenderForm } from '@inbiz/render';
import { inbiz } from '@inbiz/core';
import { queryDataInfo } from './service';
import { containerType } from '@inbiz/utils';
import './dataDetails.less';
import { hasAuth } from '@inbiz/basic/AuthForm';
import { TextWidget, getMessage } from '@inbiz/react';
import { useInbizRouter } from '@inbiz/hooks';

type IDataDetails = {
  modelKey: string;
  modelKeyName: string;
  list: {
    [key: string]: string | number | boolean | object | object[];
  }[];
  operations: any;
  inbiz: inbiz;
  updateList: any;
  emit: any;
  events: any;
  auth?: any;
  modelname?: string;
  children: ReactElement
};

function DataDetails({
  modelKeyName,
  list,
  inbiz,
  operations,
  updateList,
  events,
  emit,
  auth,
  modelname,
  children
}: IDataDetails) {
  const history = useInbizRouter();
  const { location } = history;
  const container = useMemo(
    () =>
      inbiz.browser.designer
        ? document.querySelector('.rootContainer') || document.body
        : document.body,
    [],
  );
  const actions = useMemo(() => {
    return operations
      .filter((item: any) => {
        const operationType =
          item?.actionType == 'view'
            ? 'select'
            : item?.actionType == 'del'
              ? 'delete'
              : item?.actionType;
        const authFlag = hasAuth(
          { table: [{ ...item, operationType: operationType }], auth: auth },
          operationType,
          inbiz?.auth,
        ).auth;
        if (authFlag) return item;
      })
      .map((item: any, index: number) => {
        return {
          text: getMessage(item.actionName),
          key: item.id,
          page: item.page?.split(',')[1],
          pageRout: item.page?.split(',')[0],
          operation: item.actionType,
        };
      })
      .filter((item: any) => item.operation !== 'add');
  }, [operations, auth, inbiz?.auth]);

  const [visible, $visible] = useState(false);
  const handleBack = useCallback(() => {
    emit?.('onClose');
    history.goBack();
  }, []);

  const handleActions = useCallback(
    async (action) => {
      let id = location?.query.id;
      const data = list.find((item) => item[modelKeyName] == id)!;
      emit?.('onClick', action.operation, action, data);
      const result = await events.current.onBeforeOperationAsync?.(action, data);
      if (result === false) {
        return;
      }
      switch (action.operation) {
        case 'view':
        case 'edit':
          //@ts-ignore
          // emit(
          //   `on${action.operation as 'read' | 'edit'}`,
          //   operations.filter((item: any) => {
          //     return item.actionType == action.operation;
          //   })[0],
          //   data,
          // );
          // emit?.('onClick', action.operation);
          if (action.operation === 'add') {
            id = '';
          }
          const urlData = events?.current.onOpenChildUrl?.(action, data);
          if (action.operation == 'edit') {
            emit?.('onOpen');
          }
          if (action.pageRout) {
            //@ts-ignore
            history.push({
              pathname: location.pathname + '/' + `eformtable${action.operation}`,
              // @ts-ignore
              query: {
                ...location?.query,
                id,
                pageRout: action.pageRout,
                ...urlData,
              },
            });
          } else {
            Toast.show({
              content: getMessage('Table.tips.pleaseBindThePage'),
            });
          }
          break;
        case 'del':
          Dialog.confirm({
            content: getMessage('Table.tips.confirmDeletion'),
            confirmText: <TextWidget>Table.sure</TextWidget>,
            cancelText: <TextWidget>Table.cancel</TextWidget>,
            onConfirm: async () => {
              const resData = await inbiz?.submit({
                modleName: modelname,
                data: [{ id, _opt: 'del' }],
                noRelation: true,
              });
              if (!resData) return;
              emit('ondelete', data);
              updateList(`eformtable${action.operation}`, undefined, id);
              emit?.('onClose');
              history.goBack();
            },
          });
          break;
        case 'custom':
          emit(`on${action.operation as 'custom'}`, action, data);
          break;
      }
    },
    [operations, location],
  );

  return createPortal(
    <div className="eformDataGrid dataDetails">
      <NavBar
        back={
          <span style={{ color: 'var( --inbiz-color-text)', fontSize: '16px' }}>
            {getMessage('Table.return')}
          </span>
        }
        onBack={handleBack}
        right={
          (actions?.length ?? 0) > 0 && <MoreOutline fontSize={24} onClick={() => $visible(true)} />
        }
      >
        <TextWidget>Table.detail</TextWidget>
      </NavBar>
      <div className="detailContent">{children}</div>
      {operations?.length ? (
        <>
          <div className="operation"></div>
          <ActionSheet
            popupClassName={'actionSheetPop'}
            actions={actions}
            visible={visible}
            cancelText={getMessage('Table.button.cancel')}
            onClose={() => $visible(false)}
            closeOnAction
            onAction={handleActions}
          />
        </>
      ) : null}
      <Outlet />
    </div>,
    container,
  );
}

export default DataDetails;

type IDetailPage = {
  updateList: IDataDetails['updateList'];
  filterLazy: string;
  appId: string;
  sourceModel: string;
  inbiz: IPorps['inbiz'];
  emit: IPorps['emit'];
  events: MutableRefObject<IPorps['callBackEvents']>;
};
export function DetailPage({
  inbiz,
  filterLazy,
  appId,
  sourceModel,
  updateList,
  events,
  emit,
}: IDetailPage) {
  const history = useInbizRouter();
  const { type } = useParams();
  const { location } = history;
  const isShowSave = type !== 'eformtableview';
  const pageRef = useRef<any>(null);
  const [page] = useState({ name: '' });
  const handleInit = useCallback(() => {
    if (pageRef?.current) {
      emit?.('onSubPageInit', pageRef.current.page);
      pageRef.current?.page.off('pageMount._h5table');
      pageRef.current?.page.on('pageMount._h5table', () => {
        return pageRef?.current && emit?.('onSubPageMount', pageRef.current.page);
      });
    }
    // 页面保存时触发
    pageRef.current?.page.off('saveData._h5table');
    pageRef.current?.page.on('saveData._h5table', async (_data: any, res: object) => {
      //@ts-ignore
      const newId = type === 'eformtableadd' ? res.data : location.query.id;
      const queryInfo = events.current.onDataEdited || queryDataInfo;
      queryInfo({
        appId: appId,
        recordId: newId,
        filterLazy,
        key: sourceModel,
      }).then((res: any) => {
        if (res.Rows?.length) {
          updateList(type, res.Rows[0], newId);
        }
        emit('onupdateItem', res, type);
        if (type == 'eformtableadd') {
          emit('onAdd', res, type);
        } else {
          emit('onEdit', res, type);
        }
        emit?.('onClose');
        history.goBack();
      });
    });
  }, []);
  const handleSave = useCallback(() => {
    // 执行保存操作
    return pageRef.current?.page.submit();
  }, []);
  return (
    <div className="detailPage">
      <NavBar
        back={
          <span style={{ color: 'var( --inbiz-color-text)', fontSize: '16px' }}>
            {getMessage('Table.return')}
          </span>
        }
        onBack={() => {
          isShowSave && emit?.('onClose');
          history.goBack();
        }}
        right={
          isShowSave && (
            <Button
              onClick={handleSave}
              color="primary"
              size="small"
              fill="none"
              style={{ color: 'var(--inbiz-color-primary)', fontSize: '16px' }}
            >
              <TextWidget>Table.button.save</TextWidget>
            </Button>
          )
        }
      >
        {page.name}
      </NavBar>
      <RenderForm
        ref={pageRef}
        key={`${(location as unknown as { query: { outId: string } }).query.outId}_${containerType.LAYOUT_CONTENT || containerType.LAYOUT_CONTENT
          }`}
        id={location.query.pageRout as string}
        globalSDK={inbiz!.getGlobalSDK?.()}
        queryData={type=='eformtableview'?{ id: (location as unknown as { query: { id: string } }).query.id,_viewMode:'look'}:{ id: (location as unknown as { query: { id: string } }).query.id}}
        onInit={handleInit}
        type={'page'}
      />
    </div>
  );
}
